#include "jse_manager.h"
#include "jse_env.h"
#include "jse_log.h"
#include <future>



javascript_manager javascript_manager::manager_;

javascript_manager::javascript_manager()
{
    jse_log::get().init();
}

javascript_manager& javascript_manager::get()
{
    return manager_;
}

bool javascript_manager::thread_entry(std::shared_ptr<javascript_environment> env)
{
    if(!env->init()) {
        env->set_init_result(false);
        return false;
    }
    //这里同步一下
    env->set_init_result(true);
    //执行uv循环
    return env->exec();
}

int javascript_manager::create_env()
{
    auto env = std::make_shared<javascript_environment>();
    auto f = std::async(std::launch::async, &javascript_manager::thread_entry, this, env);
    auto pack = std::make_shared<javascript_env_pack>(env, f);
    bool r = pack->env->get_init_result();
    if(!r) {
        pack->f.get();
        //LOG ERROR
        return -1;
    }
    count_++;
    envs_.emplace(count_, pack);
    return count_;
}

bool javascript_manager::close_env(int id)
{
    auto it = envs_.find(id);
    if(it == envs_.end())
        return false;
    return envs_.at(it->first)->close();
}

void javascript_manager::close_all()
{
    for(auto& pair : envs_) {
        pair.second->close();
    }
    envs_.clear();
}

qjs::Value javascript_manager::eval_javascript_string(int id, const std::string& javascript)
{
    auto it = envs_.find(id);
    if(it == envs_.end())
        return qjs::Value{nullptr, JS_UNDEFINED};
    return envs_.at(it->first)->env->eval_javascript_string(javascript);
}

qjs::Value javascript_manager::eval_javascript_file(int id, const std::string& filepath)
{
    auto it = envs_.find(id);
    if(it == envs_.end())
        return qjs::Value{nullptr, JS_UNDEFINED};
    return envs_.at(it->first)->env->eval_javascript_file(filepath);
}
